package com.OrderingSystem.service.impl;

import cn.hutool.core.util.IdUtil;
import com.OrderingSystem.dto.CartDTO;
import com.OrderingSystem.dto.OrderDTO;
import com.OrderingSystem.dto.OrderDetailsDTO;
import com.OrderingSystem.enums.OrderStatusEnum;
import com.OrderingSystem.enums.PayStatusEnum;
import com.OrderingSystem.enums.ResultEnum;
import com.OrderingSystem.exception.SellException;
import com.OrderingSystem.mapper.OrderDetailMapper;
import com.OrderingSystem.mapper.ProductInfoMapper;
import com.OrderingSystem.pojo.OrderDetail;
import com.OrderingSystem.pojo.OrderMaster;
import com.OrderingSystem.mapper.OrderMasterMapper;
import com.OrderingSystem.pojo.ProductInfo;
import com.OrderingSystem.service.IOrderDetailService;
import com.OrderingSystem.service.IOrderMasterService;
import com.OrderingSystem.service.IProductInfoService;
import com.OrderingSystem.utils.Result;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author Chenlin
 * @since 2025-08-13
 */
@Slf4j
@Service
public class OrderMasterServiceImpl extends ServiceImpl<OrderMasterMapper, OrderMaster> implements IOrderMasterService {

    @Autowired
    ProductInfoMapper productInfoMapper;

    @Autowired
    OrderMasterMapper orderMasterMapper;

    @Autowired
    OrderDetailMapper orderDetailMapper;


    @Transactional // 事务注解, 保证数据一致性, 要么都成功, 要么都失败
    @Override
    public OrderDTO createOrder(OrderDTO orderDTO) {
        // 雪花算法获取ID: 生产一个随时永远不重复的订单号
        //String orderId = String.valueOf(IdUtil.getSnowflake().nextId());
        // 订单总金额用 BigDecimal
        BigDecimal orderAmount = new BigDecimal(BigInteger.ZERO);
        //1. 查询商品（数量, 价格）
        for (OrderDetail orderDetail : orderDTO.getOrderDetailList()) {
            // 根据商品ID查询一下商品
            // ProductInfo productInfo = productInfoService.getById(orderDetail.getProductId());
            ProductInfo productInfo = productInfoMapper.selectById(orderDetail.getProductId());
            if (productInfo == null) {
                throw new SellException(ResultEnum.PRODUCT_NOT_EXIST);
            }
            //2. 计算订单总价
            orderAmount = productInfo.getProductPrice().multiply(new BigDecimal(orderDetail.getProductQuantity())).add(orderAmount);
            //订单详情入库
            //orderDetail.setDetailId(String.valueOf(IdUtil.simpleUUID()));
            //orderDetail.setOrderId(orderId);
            BeanUtils.copyProperties(productInfo, orderDetail);
            // 注意：此时不保存orderDetail，因为还没有orderId
            //【新增订单详情order_detail】
            // orderDetailService.save(orderDetail);
        }
        //3. 写入订单数据库（orderMaster和orderDetail）
        OrderMaster orderMaster = new OrderMaster();
        //orderDTO.setOrderId(orderId);
        BeanUtils.copyProperties(orderDTO, orderMaster);
        orderMaster.setOrderAmount(orderAmount);
        orderMaster.setOrderStatus(OrderStatusEnum.NEW.getCode());
        orderMaster.setPayStatus(PayStatusEnum.WAIT.getCode());
        //【新增订单详情order_master】
        orderMasterMapper.insert(orderMaster);
        // 获取数据库生成的订单ID
        Integer orderId = orderMaster.getOrderId();

        //4. 扣库存
        List<OrderDetail> orderDetailList = orderDTO.getOrderDetailList();
        for (OrderDetail orderDetail : orderDetailList) {
            // 设置订单详情的订单ID
            orderDetail.setOrderId(orderId);
            // 订单详情ID使用数据库自增
            orderDetail.setDetailId(null);
            //【新增订单详情order_detail】
            orderDetailMapper.insert(orderDetail);

            //扣库存前检查库存是否充足
            Integer productId = orderDetail.getProductId();
            Integer productQuantity = orderDetail.getProductQuantity();
            //ProductInfo productInfo = productInfoService.getById(productId);
            ProductInfo productInfo = productInfoMapper.selectById(productId);
            if (productInfo == null) {
                throw new SellException(ResultEnum.PRODUCT_NOT_EXIST);
            }
            int result = productInfo.getProductStock() - productQuantity;
            if (result < 0) {
                //库存不足
                throw new SellException(ResultEnum.PRODUCT_STOCK_ERROR);
            }
            productInfo.setProductStock(result);
            //【更新商品的库存】
            //productInfoService.updateById(productInfo);
            productInfoMapper.updateById(productInfo);
        }
        orderDTO.setOrderId(orderId);
        return orderDTO;
    }

    @Override
    public List<OrderMaster> selectAllOrderMaster(Integer pageNum, Integer pageSize, OrderMaster orderMaster) {
        QueryWrapper<OrderMaster> queryWrapper = new QueryWrapper<>();
        queryWrapper.like(orderMaster.getBuyerName() != null, "buyer_name", orderMaster.getBuyerName());

        return orderMasterMapper.selectList(queryWrapper);
    }

    @Override
    public List<OrderDTO> findList(String openid) {
        List<OrderDTO> orderDTOList=new ArrayList<OrderDTO>();
        List<OrderMaster> orderMasterList = orderMasterMapper.selectList(new QueryWrapper<OrderMaster>().eq("buyer_openid", openid).orderByDesc("create_time"));
        for (OrderMaster orderMaster : orderMasterList) {
            OrderDTO orderDTO=new OrderDTO();
            BeanUtils.copyProperties(orderMaster, orderDTO);
            orderDTOList.add(orderDTO);
        }
        return orderDTOList;
    }

    /**
     * 查询订单详情
     */
    @Transactional
    @Override
    public OrderDetailsDTO findOrderInfo(String openid, String orderId) {
        OrderMaster orderMaster = orderMasterMapper.selectById(orderId);
        if (orderMaster == null) {
            throw new SellException(ResultEnum.ORDER_NOT_EXIST);
        }
        //查询订单详情
        List<OrderDetail> orderDetailList = orderDetailMapper.selectList(new QueryWrapper<OrderDetail>().eq("order_id", orderId));
        if (CollectionUtils.isEmpty(orderDetailList)) {
            throw new SellException(ResultEnum.ORDERDETAIL_NOT_EXIST);
        }
        OrderDetailsDTO orderDetailsDTO = new OrderDetailsDTO();
        orderDetailsDTO.setOrderId(orderId);
        BeanUtils.copyProperties(orderMaster, orderDetailsDTO);
        orderDetailsDTO.setOrderDetailList(orderDetailList);
        //orderDetailsDTO.setCreateTime(DateUtils.parseDate(orderMaster.getCreateTime()));
        //orderDetailsDTO.setUpdateTime(DateUtils.parseDate(orderMaster.getUpdateTime()));
        // 将 LocalDateTime 转换为 Date
        Date createTime = Date.from(orderMaster.getCreateTime().atZone(ZoneId.systemDefault()).toInstant());
        orderDetailsDTO.setCreateTime(createTime);
        Date updateTime = Date.from(orderMaster.getUpdateTime().atZone(ZoneId.systemDefault()).toInstant());
        orderDetailsDTO.setUpdateTime(updateTime);
        //判断是否是自己的订单
        if (!orderDetailsDTO.getBuyerOpenid().equalsIgnoreCase(openid)) {
            log.error("【查询订单】订单的openid不一致. openid={}, orderDTO={}", openid, orderDetailsDTO);
            throw new SellException(ResultEnum.ORDER_OWNER_ERROR);
        }
        return orderDetailsDTO;
    }

    @Override
    public void cancelOrder(String openid, String orderId) {
        OrderMaster orderMaster = orderMasterMapper.selectById(orderId);
        if (orderMaster == null) {
            log.error("【取消订单】查不到改订单, orderId={}", orderId);
            throw new SellException(ResultEnum.ORDER_NOT_EXIST);
        }
        //判断是否是自己的订单
        if (!orderMaster.getBuyerOpenid().equalsIgnoreCase(openid)) {
            log.error("【查询订单】订单的openid不一致. openid={}, orderDTO={}", openid, orderMaster);
            throw new SellException(ResultEnum.ORDER_OWNER_ERROR);
        }
        OrderMaster order = new OrderMaster();
        //判断订单状态
        if (!orderMaster.getOrderStatus().equals(OrderStatusEnum.NEW.getCode())) {
            log.error("【取消订单】订单状态不正确, orderId={}, orderStatus={}", orderMaster.getOrderId(), orderMaster.getOrderStatus());
            throw new SellException(ResultEnum.ORDER_STATUS_ERROR);
        }
        //修改订单状态
        orderMaster.setOrderStatus(OrderStatusEnum.CANCEL.getCode());
        int i = orderMasterMapper.updateById(orderMaster);
        log.info("【取消订单】更新成功, orderMaster={}", orderMaster);
        if (i <= 0) {
            log.error("【取消订单】更新失败, orderMaster={}", orderMaster);
            throw new SellException(ResultEnum.ORDER_UPDATE_FAIL);
        }

        List<OrderDetail> orderDetailList = orderDetailMapper.selectList(new QueryWrapper<OrderDetail>().eq("order_id", orderId));

        //返回库存
        if (CollectionUtils.isEmpty(orderDetailList)) {
            log.error("【取消订单】订单中无商品详情, orderId={}", orderId);
            throw new SellException(ResultEnum.ORDER_DETAIL_EMPTY);
        }
        List<CartDTO> cartDTOList = orderDetailList.stream()
                .map(e -> new CartDTO(String.valueOf(e.getProductId()), e.getProductQuantity()))
                .collect(Collectors.toList());


        //恢复库存
        for (CartDTO cartDTO : cartDTOList) {
            ProductInfo productInfo = productInfoMapper.selectById(cartDTO.getProductId());
            if (productInfo == null) {
                throw new SellException(ResultEnum.PRODUCT_NOT_EXIST);
            }
            Integer result = productInfo.getProductStock() + cartDTO.getProductQuantity();
            productInfo.setProductStock(result);
            productInfoMapper.updateById(productInfo);
        }
    }

    @Override
    public Integer getTodayOrderCount() {
        QueryWrapper<OrderMaster> queryWrapper = new QueryWrapper<>();
        queryWrapper.apply("DATE(create_time) = CURDATE()");
        return orderMasterMapper.selectCount(queryWrapper);
    }

    @Override
    public BigDecimal getTotalOrderAmount() {
        QueryWrapper<OrderMaster> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("SUM(order_amount) as totalAmount");
        List<Object> result = orderMasterMapper.selectObjs(queryWrapper);
        if (result != null && !result.isEmpty() && result.get(0) != null) {
            return new BigDecimal(result.get(0).toString());
        }
        return BigDecimal.ZERO;
    }


}
